home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994 June: Reference Library / Dev.CD Jun 94.toast / Periodicals / develop / develop Issue 18 / develop 18 code / OSA Sample / Sources / PascalString.cp < prev    next >
Encoding:
Text File  |  1993-07-19  |  17.8 KB  |  647 lines  |  [TEXT/MPS ]

  1. //----------------------------------------------------------------------------------------
  2. // PascalString.cp 
  3. // Copyright © 1985-1992 by Apple Computer, Inc.  All rights reserved.
  4. //----------------------------------------------------------------------------------------
  5.  
  6.  
  7. #include "PascalString.h"
  8.  
  9. #ifndef __STDIO__
  10. #include <StdIo.h>
  11. #endif
  12.  
  13. #ifndef __STRING__
  14. #include <String.h>
  15. #endif
  16.  
  17.  
  18. #pragma segment Main
  19.  
  20.  
  21. //========================================================================================
  22. // CLASS CString
  23. //========================================================================================
  24.  
  25. CString::CString()
  26. {
  27. }
  28.  
  29. CString::~CString()
  30. {
  31. }
  32.  
  33.  
  34. CStr255::CStr255()
  35. {
  36. }
  37.  
  38. CStr255::~CStr255()
  39. {
  40. }
  41.  
  42.  
  43. CStr63::CStr63()
  44. {
  45. }
  46.  
  47. CStr63::~CStr63()
  48. {
  49. }
  50.  
  51. CStr32::CStr32()
  52. {
  53. }
  54.  
  55. CStr32::~CStr32()
  56. {
  57. }
  58.  
  59. CStr31::CStr31()
  60. {
  61. }
  62.  
  63. CStr31::~CStr31()
  64. {
  65. }
  66.  
  67.  
  68.  
  69. //----------------------------------------------------------------------------------------
  70. // CString::InsertHelper(CString):
  71. //----------------------------------------------------------------------------------------
  72.  
  73. void CString::InsertHelper(const CString& insStr,
  74.                           short pos,
  75.                           short maxLength)
  76. {
  77.     if (pos > Length() + 1)
  78.     {
  79. #if qDebugMsg
  80.         fprintf(stderr, "###CString::InsertHelper: Insert position greater than length of CString.\n");
  81. #endif
  82.         if (Length() < maxLength)    
  83.             pos = Length() + 1;
  84.     }
  85.     
  86. #if qDebugMsg
  87.     if (Length() + insStr.Length() > maxLength)
  88.         fprintf(stderr, "### CString::InsertHelper: CString truncated during insert call.\n");    
  89. #endif
  90.  
  91.     short usableLengthOfInsertString;
  92.     short endPosOfInsertString;
  93.     short usableLengthOfShiftedString;
  94.     
  95.     if (pos + insStr.Length() > maxLength)
  96.         usableLengthOfInsertString = maxLength - pos + 1;
  97.     else
  98.         usableLengthOfInsertString = insStr.Length();
  99.     endPosOfInsertString = pos + usableLengthOfInsertString - 1;
  100.     
  101.     if ((endPosOfInsertString + 1) + (Length() - pos + 1) > maxLength)
  102.         usableLengthOfShiftedString = maxLength - endPosOfInsertString;
  103.     else
  104.         usableLengthOfShiftedString = Length() - pos + 1;
  105.         
  106.     memmove(&fStr[endPosOfInsertString + 1], &fStr[pos], usableLengthOfShiftedString);
  107.     memmove(&fStr[pos], &insStr.fStr[1], usableLengthOfInsertString);
  108.     Length() = usableLengthOfShiftedString + endPosOfInsertString;
  109. } // CString::InsertHelper(CString)
  110.  
  111.  
  112. //----------------------------------------------------------------------------------------
  113. // CString::InsertHelper(char*):
  114. //----------------------------------------------------------------------------------------
  115.  
  116. void CString::InsertHelper(const char* insStr,
  117.                           short pos,
  118.                           short maxLength)
  119. {
  120.     this->InsertHelper(CStr255(insStr), pos, maxLength);
  121. } // CString::InsertHelper(char*)
  122.  
  123.  
  124. //----------------------------------------------------------------------------------------
  125. // CString::operator[]: !!! we'd ideally like this method to be inlined but CFront doesn't
  126. // seem to want to inline it for us !!!
  127. //----------------------------------------------------------------------------------------
  128.  
  129. unsigned char& CString::operator[](short pos)
  130. {
  131.     return fStr[pos];
  132. } // CString::operator[] for non-const CString
  133.  
  134.  
  135. //----------------------------------------------------------------------------------------
  136. // CString::operator char*:
  137. //----------------------------------------------------------------------------------------
  138.  
  139. CString::operator char*() const
  140. {
  141.     const short kTempCStrings = 4;
  142.     static short currentCString = 0;
  143.     static char cStrings[kTempCStrings][kStr255Len+1];
  144.     
  145.     currentCString = (currentCString + 1) % kTempCStrings;
  146.     
  147.     strncpy(cStrings[currentCString], (char *) &fStr[1], Length());
  148.     cStrings[currentCString][Length()] = '\0';
  149.     
  150.     return cStrings[currentCString];
  151. } // CString::operator char*
  152.  
  153. CString::operator const unsigned char*() const
  154. {
  155.      return (const unsigned char *) this;
  156. }
  157.  
  158.  
  159. //----------------------------------------------------------------------------------------
  160. // CString::operator long:
  161. //----------------------------------------------------------------------------------------
  162.  
  163. CString::operator long() const
  164. {
  165.     // The following statement looks like it should work. Right?
  166.     //
  167.     //    return *((long *) &fStr[1]);
  168.     //
  169.     // Wrong, the C compiler generates a MOVE.L starting on a odd byte boundary for the
  170.     // preceding statement. This is illegal on the 68000. But its _NOT_ a bug, because
  171.     // according to the ANSI C reference manual, "A pointer to one type may be converted
  172.     // to a pointer to another type. The resulting pointer may cause an addressing
  173.     // exception if the subject pointer does not refer to an object suitably aligned in
  174.     // storage".
  175.     
  176.     long returnLong;
  177.     
  178.     memcpy(&returnLong, &fStr[1], sizeof(long));
  179.     return returnLong;
  180. } // CString::operator long
  181.  
  182.  
  183. //----------------------------------------------------------------------------------------
  184. // CString::Pos(char*):
  185. //----------------------------------------------------------------------------------------
  186.  
  187. unsigned char CString::Pos(const char* subStr, unsigned char startPos)
  188. {
  189.     char cStr[kStr255Len + 1];
  190.     char* ptr;
  191.     
  192.     memcpy(cStr, &fStr[1], Length());
  193.     cStr[Length()] = 0;
  194.     ptr = strstr(&cStr[startPos - 1], subStr);
  195.     return ptr != NULL ? (ptr - cStr) + 1 : 0;
  196. } // CString::Pos(char*)
  197.  
  198.  
  199. //----------------------------------------------------------------------------------------
  200. // CString::Pos(CString):
  201. //----------------------------------------------------------------------------------------
  202.  
  203. unsigned char CString::Pos(const CString& subStr, unsigned char startPos)
  204. {
  205.     char cStr[kStr255Len + 1];
  206.  
  207.     memcpy(cStr, &subStr.fStr[1], subStr.Length());
  208.     cStr[subStr.Length()] = 0;
  209.     return this->Pos(cStr, startPos);
  210. } // CString::Pos(CString)
  211.  
  212.  
  213.  
  214. //========================================================================================
  215. // CLASS CStr255
  216. //========================================================================================
  217.  
  218.  
  219. //----------------------------------------------------------------------------------------
  220. // CStr255::CStr255(char*):
  221. //----------------------------------------------------------------------------------------
  222.  
  223. CStr255::CStr255(const char* str)
  224. {
  225.     // Truncate the C CString to 255 bytes if necessary.
  226.  
  227.     Length() = str == NULL ? 0 : strlen(str);
  228.     
  229.     if (Length() > kStr255Len)
  230.         Length() = kStr255Len;
  231.     memcpy(&fStr[1], str, Length());
  232. } // CStr255::CStr255(char*)
  233.  
  234.  
  235. //----------------------------------------------------------------------------------------
  236. // CStr255::CStr255(long): Useful for converting OSType's into CStr255's.
  237. //----------------------------------------------------------------------------------------
  238.  
  239. CStr255::CStr255(const long id)
  240. {
  241.     Length() = 4;
  242.     memcpy(&fStr[1], &id, Length());
  243. } // CStr255::CStr255(long)
  244.  
  245.  
  246. //----------------------------------------------------------------------------------------
  247. // CStr255::Copy:
  248. //----------------------------------------------------------------------------------------
  249.  
  250. CStr255 CStr255::Copy(short pos, short length)
  251. {
  252.     CStr255 newString;
  253.     
  254.     length = length > Length() - pos + kLengthByte ? Length() - pos + kLengthByte : length;
  255.     
  256.     if (length > 0)
  257.     {
  258.         memcpy(&newString.fStr[1], &fStr[pos], length);
  259.         newString.Length() = length;
  260.     }
  261.     else
  262.         newString = "";
  263.         
  264.     return newString;
  265.     
  266. } // CStr255::Copy
  267.  
  268.  
  269. //----------------------------------------------------------------------------------------
  270. // CStr255::operator+:
  271. //----------------------------------------------------------------------------------------
  272.  
  273. CStr255 operator+(const CString& s1,
  274.                   const char* s2)
  275. {
  276.     CStr255 newStr;
  277.     short s2Len = s2 == NULL ? 0 : strlen((const char *) s2);
  278.  
  279.     if (s1.Length() + s2Len > kStr255Len)
  280.         newStr.Length() = kStr255Len;
  281.     else
  282.         newStr.Length() = s1.Length() + s2Len;
  283.         
  284.     memcpy(&newStr.fStr[1], &s1.fStr[1], s1.Length());
  285.     memcpy(&newStr.fStr[s1.Length() + kLengthByte], s2, newStr.Length() - s1.Length());
  286.  
  287.     return newStr;
  288. } // CStr255::operator+
  289.  
  290.  
  291. //----------------------------------------------------------------------------------------
  292. // CStr255::operator+(char*,CString):
  293. //----------------------------------------------------------------------------------------
  294.  
  295. CStr255 operator+(const char* s1,
  296.                   const CString& s2)
  297. {
  298.     CStr255 newStr;
  299.     short s1Len = s1 == NULL ? 0 : strlen((const char *) s1);
  300.  
  301.     if (s1Len + s2.Length() > kStr255Len)
  302.         newStr.Length() = kStr255Len;
  303.     else
  304.         newStr.Length() = s1Len + s2.Length();
  305.         
  306.     memcpy(&newStr.fStr[1], s1, s1Len);
  307.     memcpy(&newStr.fStr[s1Len + kLengthByte], s2.fStr + 1, newStr.Length() - s1Len);
  308.  
  309.     return newStr;
  310. } // CStr255::operator+(char*,CString)
  311.  
  312.  
  313. //----------------------------------------------------------------------------------------
  314. // CStr255::operator+(CString,CString):
  315. //----------------------------------------------------------------------------------------
  316.  
  317. CStr255 operator+(const CString& s1,
  318.                   const CString& s2)
  319. {
  320.     CStr255 newStr;
  321.  
  322.     if (s1.Length() + s2.Length() > kStr255Len)
  323.         newStr.Length() = kStr255Len;
  324.     else
  325.         newStr.Length() = s1.Length() + s2.Length();
  326.         
  327.     memcpy(&newStr.fStr[1], &s1.fStr[1], s1.Length());
  328.     memcpy(&newStr.fStr[s1.Length() + kLengthByte], s2.fStr + 1, newStr.Length() - s1.Length());
  329.  
  330.     return newStr;
  331. } // CStr255::operator+(CString,CString)
  332.  
  333.  
  334. //----------------------------------------------------------------------------------------
  335. // CStr255::operator +=(CString):  Concatinate a string
  336. //----------------------------------------------------------------------------------------
  337.  
  338. CStr255& CStr255::operator += (const CString& str)
  339. {
  340.     InsertHelper (str, Length() + 1, kStr255Len);
  341.     return *this;
  342. } // CStr255::operator +=(CString)
  343.  
  344.  
  345. //----------------------------------------------------------------------------------------
  346. // CStr255::operator +=(char*):  Concatinate a string
  347. //----------------------------------------------------------------------------------------
  348.  
  349. CStr255& CStr255::operator += (const char* str)
  350. {
  351.     InsertHelper (str, Length() + 1, kStr255Len);
  352.     return *this;
  353. } // CStr255::operator +=(char*)
  354.  
  355.  
  356. //----------------------------------------------------------------------------------------
  357. // CStr255::operator +=(char):  Concatinate a single character
  358. //----------------------------------------------------------------------------------------
  359.  
  360. CStr255& CStr255::operator += (const char ch)
  361. {
  362.     if (++Length() <= kStr255Len)
  363.         fStr[Length()] = ch;
  364.     else
  365.     {
  366.         --Length();
  367. #if qDebugMsg
  368.         fprintf(stderr, "###CStr255::operator+=: Concatenation produces CStr255 overflow.\n");
  369. #endif
  370.     }
  371.     
  372.     return *this;
  373. } // CStr255::operator +=(char)
  374.  
  375.  
  376. //----------------------------------------------------------------------------------------
  377. // CStr255::operator =:
  378. //----------------------------------------------------------------------------------------
  379.  
  380. CStr255& CStr255::operator = (const char* str)
  381. {
  382.     if (str)
  383.     {
  384.         // Truncate the C CString to 255 bytes if necessary.
  385.         register size_t itsSize = strlen(str);
  386.         if (itsSize > kStr255Len)
  387.             Length() = kStr255Len;
  388.         else
  389.             Length() = itsSize;
  390.  
  391.         memcpy(&fStr[1], str, Length());
  392.     }
  393.     else
  394.         Length() = 0;
  395.     
  396.     return *this;
  397. } // CStr255::operator =
  398.  
  399.  
  400.  
  401. //========================================================================================
  402. // CLASS CStr63
  403. //========================================================================================
  404.  
  405.  
  406. //----------------------------------------------------------------------------------------
  407. // CStr63::CStr63(char*):
  408. //----------------------------------------------------------------------------------------
  409.  
  410. CStr63::CStr63(const char* str)
  411. {
  412.     // Truncate the C CString to 63 bytes if necessary.
  413.  
  414.     Length() = str == NULL ? 0 : strlen((const char*)str);
  415.     if (Length() > kStr63Len)
  416.         Length() = kStr63Len;
  417.     memcpy(&fStr[1], str, Length());
  418. } // CStr63::CStr63(char*)
  419.  
  420.  
  421. //----------------------------------------------------------------------------------------
  422. // CStr63::CStr63(long):
  423. //----------------------------------------------------------------------------------------
  424.  
  425. CStr63::CStr63(const long id)
  426. {
  427.     Length() = 4;
  428.     memcpy(&fStr[1], &id, Length());
  429. } // CStr63::CStr63(long)
  430.  
  431.  
  432. //----------------------------------------------------------------------------------------
  433. // CStr63::Copy:
  434. //----------------------------------------------------------------------------------------
  435.  
  436. CStr63 CStr63::Copy(short pos, short length)
  437. {
  438.     CStr63 newString;
  439.     
  440.     length = length > Length() - pos + kLengthByte ? Length() - pos + kLengthByte : length;
  441.     
  442.     if (length > 0)
  443.     {
  444.         memcpy(&newString.fStr[1], &fStr[pos], length);
  445.         newString.Length() = length;
  446.     }
  447.     else
  448.         newString = "";
  449.         
  450.     return newString;
  451.     
  452. } // CStr63::Copy
  453.  
  454.  
  455. //----------------------------------------------------------------------------------------
  456. // CStr63::operator +=(CString):  Concatinate a string
  457. //----------------------------------------------------------------------------------------
  458.  
  459. CStr63& CStr63::operator += (const CString& str)
  460. {
  461.     InsertHelper (str, Length() + 1, kStr63Len);
  462.     return *this;
  463. } // CStr63::operator +=(CString)
  464.  
  465.  
  466. //----------------------------------------------------------------------------------------
  467. // CStr63::operator +=(char*):  Concatinate a string
  468. //----------------------------------------------------------------------------------------
  469.  
  470. CStr63& CStr63::operator += (const char* str)
  471. {
  472.     InsertHelper (str, Length() + 1, kStr63Len);
  473.     return *this;
  474. } // CStr63::operator +=(char*)
  475.  
  476.  
  477. //----------------------------------------------------------------------------------------
  478. // CStr63::operator +=(char):  Concatinate a single character
  479. //----------------------------------------------------------------------------------------
  480.  
  481. CStr63& CStr63::operator += (const char ch)
  482. {
  483.     if (++Length() <= kStr63Len)
  484.         fStr[Length()] = ch;
  485.     else
  486.     {
  487.         --Length();
  488. #if qDebugMsg
  489.         fprintf(stderr, "###CStr63::operator+=: Concatenation produces CStr63 overflow.\n");
  490. #endif
  491.     }
  492.     
  493.     return *this;
  494. } // CStr63::operator +=(char)
  495.  
  496.  
  497.  
  498. //========================================================================================
  499. // CLASS CStr32
  500. //========================================================================================
  501.  
  502.  
  503. //----------------------------------------------------------------------------------------
  504. // CStr32::CStr32(char*):
  505. //----------------------------------------------------------------------------------------
  506.  
  507. CStr32::CStr32(const char* str)
  508. {
  509.     // Truncate the C CString to 32 bytes if necessary.
  510.  
  511.     Length() = str == NULL ? 0 : strlen((const char*)str);
  512.     if (Length() > kStr32Len)
  513.         Length() = kStr32Len;
  514.     memcpy(&fStr[1], str, Length());
  515. } // CStr32::CStr32(char*)
  516.  
  517.  
  518. //----------------------------------------------------------------------------------------
  519. // CStr32::CStr32(long):
  520. //----------------------------------------------------------------------------------------
  521.  
  522. CStr32::CStr32(const long id)
  523. {
  524.     Length() = 4;
  525.     memcpy(&fStr[1], &id, Length());
  526. } // CStr32::CStr32(long)
  527.  
  528.  
  529. //----------------------------------------------------------------------------------------
  530. // CStr32::Copy:
  531. //----------------------------------------------------------------------------------------
  532.  
  533. CStr32 CStr32::Copy(short pos, short length)
  534. {
  535.     CStr32 newString;
  536.     
  537.     length = length > Length() - pos + kLengthByte ? Length() - pos + kLengthByte : length;
  538.     
  539.     if (length > 0)
  540.     {
  541.         memcpy(&newString.fStr[1], &fStr[pos], length);
  542.         newString.Length() = length;
  543.     }
  544.     else
  545.         newString = "";
  546.         
  547.     return newString;
  548.  
  549. } // CStr32::Copy
  550.  
  551.  
  552.  
  553. //========================================================================================
  554. // CLASS CStr31
  555. //========================================================================================
  556.  
  557.  
  558. //----------------------------------------------------------------------------------------
  559. // CStr31::CStr31(char*):
  560. //----------------------------------------------------------------------------------------
  561.  
  562. CStr31::CStr31(const char* str)
  563. {
  564.     // Truncate the C CString to 31 bytes if necessary.
  565.  
  566.     Length() = str == NULL ? 0 : strlen((const char*)str);
  567.     if (Length() > kStr31Len)
  568.         Length() = kStr31Len;
  569.     memcpy(&fStr[1], str, Length());
  570. } // CStr31::CStr31(char*)
  571.  
  572.  
  573. //----------------------------------------------------------------------------------------
  574. // CStr31::CStr31(long):
  575. //----------------------------------------------------------------------------------------
  576.  
  577. CStr31::CStr31(const long id)
  578. {
  579.     Length() = 4;
  580.     memcpy(&fStr[1], &id, Length());
  581. } // CStr31::CStr31(long)
  582.  
  583.  
  584. //----------------------------------------------------------------------------------------
  585. // CStr31::Copy:
  586. //----------------------------------------------------------------------------------------
  587.  
  588. CStr31 CStr31::Copy(short pos, short length)
  589. {
  590.     CStr31 newString;
  591.     
  592.     length = length > Length() - pos + kLengthByte ? Length() - pos + kLengthByte : length;
  593.     
  594.     if (length > 0)
  595.     {
  596.         memcpy(&newString.fStr[1], &fStr[pos], length);
  597.         newString.Length() = length;
  598.     }
  599.     else
  600.         newString = "";
  601.         
  602.     return newString;
  603.  
  604. } // CStr31::Copy
  605.  
  606.  
  607. //----------------------------------------------------------------------------------------
  608. // CStr31::operator +=(CString):  Concatinate a string
  609. //----------------------------------------------------------------------------------------
  610.  
  611. CStr31& CStr31::operator += (const CString& str)
  612. {
  613.     InsertHelper (str, Length() + 1, kStr31Len);
  614.     return *this;
  615. } // CStr31::operator +=(CString)
  616.  
  617.  
  618. //----------------------------------------------------------------------------------------
  619. // CStr31::operator +=(char*):  Concatinate a string
  620. //----------------------------------------------------------------------------------------
  621.  
  622. CStr31& CStr31::operator += (const char* str)
  623. {
  624.     InsertHelper (str, Length() + 1, kStr31Len);
  625.     return *this;
  626. } // CStr31::operator +=(char*)
  627.  
  628.  
  629. //----------------------------------------------------------------------------------------
  630. // CStr31::operator +=(char):  Concatinate a single character
  631. //----------------------------------------------------------------------------------------
  632.  
  633. CStr31& CStr31::operator += (const char ch)
  634. {
  635.     if (++Length() <= kStr31Len)
  636.         fStr[Length()] = ch;
  637.     else
  638.     {
  639.         --Length();
  640. #if qDebugMsg
  641.         fprintf(stderr,"###CStr31::operator+=: Concatenation produces CStr31 overflow.\n");
  642. #endif
  643.     }
  644.     
  645.     return *this;
  646. } // CStr31::operator +=(char)
  647.